package com.tf.integrated.controller;

import com.alibaba.fastjson.JSONArray;
import com.ccssoft.m8.common.ccssoft.modules.util.EntityWrapperHandle;
import com.ccssoft.m8.common.web.BaseController;
import com.tf.integrated.entity.*;
import com.tf.integrated.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.alibaba.fastjson.JSONObject;
import org.omg.CORBA.INTERNAL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;


/**
 * 流量管理接口
 *
 * @author allen
 * @date: 2020年9月14日上午10:56:20
 */
@Api(value = "流量管理接口", description = "ConfigController")
@RestController
public class FlowController extends BaseController {
    @Autowired
    private EventresultvehicleinfoService<EventresultvehicleinfoEntity> vehicleService;

    @Autowired
    private EventresulttricyclesinfoService<EventresulttricyclesinfoEntity> tricycleService;

    @Autowired
    private EventresultpedestriansinfoService<EventresultpedestriansinfoEntity> pedestrianService;

    @Autowired
    private EventresultbikesinfoService<EventresultbikesinfoEntity> bikeService;

    @Autowired
    private EventresultpersonService<EventresultpersonEntity> personService;

    @Autowired
    private DeviceinfoService<DeviceinfoEntity> deviceService;

    @ApiOperation("今日流量接口")
    @GetMapping("/flow/today")
    @CrossOrigin(origins = "*", maxAge = 86400)
    public FLowDataReturnEntity<FlowJsonEntity[]> flowToday(@RequestParam Map<String, Object> data) {
        if (data != null && data.size() > 0) {
            String host = (String) data.get("host");
            String chnId = (String) data.get("chnId");
            if (isExist(host) && isExist(chnId)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                Date time = new Date();
                String now = sdf.format(time);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(time);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                long start = calendar.getTimeInMillis();
                String zero = sdf.format(calendar.getTime());
                List<JSONObject> all = new ArrayList<>();

                EntityWrapperHandle<EventresultvehicleinfoEntity> ew1 = new EntityWrapperHandle<EventresultvehicleinfoEntity>();
                ew1.setSqlSelect("type", "createtime");
                ew1.eq("deviceid", host);
                ew1.eq("chn", chnId);
                ew1.between("createtime", zero, now);
                List<EventresultvehicleinfoEntity> list1 = vehicleService.selectList(ew1);
                for (EventresultvehicleinfoEntity e1 : list1) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id", JSONObject.parseObject(e1.getType()).getIntValue("Id"));
                    jsonObject.put("time", e1.getCreatetime());
                    all.add(jsonObject);
                }

                EntityWrapperHandle<EventresulttricyclesinfoEntity> ew2 = new EntityWrapperHandle<EventresulttricyclesinfoEntity>();
                ew2.setSqlSelect("type", "createtime");
                ew2.eq("deviceid", host);
                ew2.eq("chn", chnId);
                ew2.between("createtime", zero, now);
                List<EventresulttricyclesinfoEntity> list2 = tricycleService.selectList(ew2);
                for (EventresulttricyclesinfoEntity e2 : list2) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id", JSONObject.parseObject(e2.getType()).getIntValue("Id"));
                    jsonObject.put("time", e2.getCreatetime());
                    all.add(jsonObject);
                }

                EntityWrapperHandle<EventresultpersonEntity> ew3 = new EntityWrapperHandle<EventresultpersonEntity>();
                ew3.setSqlSelect("type", "createtime");
                ew3.eq("deviceid", host);
                ew3.eq("chn", chnId);
                ew3.between("createtime", zero, now);
                List<EventresultpersonEntity> list3 = personService.selectList(ew3);
                for (EventresultpersonEntity e3 : list3) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id", JSONObject.parseObject(e3.getType()).getIntValue("Id"));
                    jsonObject.put("time", e3.getCreatetime());
                    all.add(jsonObject);
                }

                EntityWrapperHandle<EventresultbikesinfoEntity> ew4 = new EntityWrapperHandle<EventresultbikesinfoEntity>();
                ew4.setSqlSelect("type", "createtime");
                ew4.eq("deviceid", host);
                ew4.eq("chn", chnId);
                ew4.between("createtime", zero, now);
                List<EventresultbikesinfoEntity> list4 = bikeService.selectList(ew4);
                for (EventresultbikesinfoEntity e4 : list4) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id", JSONObject.parseObject(e4.getType()).getIntValue("Id"));
                    jsonObject.put("time", e4.getCreatetime());
                    all.add(jsonObject);
                }

                int[] names = new int[]{1,2,3,4,5};
                FlowJsonEntity[] array = new FlowJsonEntity[5];
                for (int i = 0; i < 5; i++) {
                    array[i] = new FlowJsonEntity();
                    array[i].setResultType(names[i]);
                    array[i].setInfo(new int[24]);
                }
                double oneHour = 3600000;
                for (JSONObject json : all) {
                    double times = json.getDate("time").getTime() - start;
                    int hour = (int) Math.floor(times / oneHour);
                    if (hour >= 0 && hour <= 23) {
                        int id = json.getIntValue("id");
                        if(id==4||id==6||id==7||id==8){
                            array[0].getInfo()[hour]++;
                        }else if(id==5){
                            array[1].getInfo()[hour]++;
                        }else if(id==9){
                            array[2].getInfo()[hour]++;
                        }else if(id==2||id==3){
                            array[3].getInfo()[hour]++;
                        }else if(id==-1||id==0){
                            array[4].getInfo()[hour]++;
                        }
                    }
                }
                return new FLowDataReturnEntity<FlowJsonEntity[]>().ok(array, 200);
            }
        }
        return new FLowDataReturnEntity<FlowJsonEntity[]>().error("params error");
    }

    @ApiOperation("流量接口")
    @GetMapping("/flow")
    @CrossOrigin(origins = "*", maxAge = 86400)
    public JSONArray flowDataList(@RequestParam Map<String, Object> data) {
        JSONArray returnData = new JSONArray();
        if (data != null && data.size() > 0) {
            String start = (String) data.get("starttime");
            String end = (String) data.get("endtime");
            if (isExist(start) && isExist(end)) {
                Integer[] types = getIntArray((String) data.get("types"));
                EntityWrapperHandle<DeviceinfoEntity> ew = new EntityWrapperHandle<DeviceinfoEntity>();
                ew.setSqlSelect("deviceid");
                List<DeviceinfoEntity> devices = deviceService.selectList(ew);
                if (devices != null && devices.size() > 0) {
                    for (DeviceinfoEntity deviceinfoEntity : devices) {
                        JSONObject device = new JSONObject();
                        device.put("deviceId", deviceinfoEntity.getDeviceid());
                        JSONArray info = new JSONArray();
                        for (int type : types) {
                            JSONObject result = new JSONObject();
                            result.put("resultType", type);
                            result.put("total", 0);
                            info.add(result);
                        }
                        device.put("info", info);
                        returnData.add(device);
                    }
                }
                List<Map<String, Object>> all = new ArrayList<>();

                EntityWrapperHandle<EventresultvehicleinfoEntity> ew1 = new EntityWrapperHandle<EventresultvehicleinfoEntity>();
                ew1.setSqlSelect("count(*)", "`type`", "deviceid");
                ew1.between("createtime", start, end);
                ew1.groupBy("`type`,deviceid");
                all.addAll(vehicleService.selectMaps(ew1));

                EntityWrapperHandle<EventresulttricyclesinfoEntity> ew2 = new EntityWrapperHandle<EventresulttricyclesinfoEntity>();
                ew2.setSqlSelect("count(*)", "`type`", "deviceid");
                ew2.between("createtime", start, end);
                ew2.groupBy("`type`,deviceid");
                all.addAll(tricycleService.selectMaps(ew2));

                EntityWrapperHandle<EventresultpedestriansinfoEntity> ew3 = new EntityWrapperHandle<EventresultpedestriansinfoEntity>();
                ew3.setSqlSelect("count(*)", "`type`", "deviceid");
                ew3.between("createtime", start, end);
                ew3.groupBy("`type`,deviceid");
                all.addAll(pedestrianService.selectMaps(ew3));

                EntityWrapperHandle<EventresultbikesinfoEntity> ew4 = new EntityWrapperHandle<EventresultbikesinfoEntity>();
                ew4.setSqlSelect("count(*)", "`type`", "deviceid");
                ew4.between("createtime", start, end);
                ew4.groupBy("`type`,deviceid");
                all.addAll(bikeService.selectMaps(ew4));

                for (Map<String, Object> e : all) {
                    int type = JSONObject.parseObject((String) e.get("type")).getIntValue("Id");
                    if (type > 9 || type < 1) {
                        type = 0;
                    }
                    if (type > types[types.length - 1]) {
                        continue;
                    }
                    String deviceid = (String) e.get("deviceid");
                    long count = (long) e.get("count(*)");
                    for (int i = 0; i < returnData.size(); i++) {
                        if (returnData.getJSONObject(i).getString("deviceId").equals(deviceid)) {
                            for (int j = 0; j < types.length; j++) {
                                if (type == types[j]) {
                                    long al = returnData.getJSONObject(i).getJSONArray("info").getJSONObject(j).getLongValue("total");
                                    returnData.getJSONObject(i).getJSONArray("info").getJSONObject(j).put("total", (al + count));
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }
        return returnData;
    }

    @ApiOperation("具体设备流量接口")
    @GetMapping("/flow/byid")
    @CrossOrigin(origins = "*", maxAge = 86400)
    public JSONArray flowDataListById(@RequestParam Map<String, Object> data) {
        JSONArray returnData = new JSONArray();
        if (data != null && data.size() > 0) {
            String start = (String) data.get("starttime");
            String end = (String) data.get("endtime");
            String host = (String) data.get("host");
            if (isExist(start) && isExist(end) && isExist(host)) {
                Integer[] types = getIntArray((String) data.get("types"));
                for (int type : types) {
                    JSONObject result = new JSONObject();
                    result.put("resultType", type);
                    result.put("total", 0);
                    returnData.add(result);
                }
                List<Map<String, Object>> all = new ArrayList<>();

                EntityWrapperHandle<EventresultvehicleinfoEntity> ew1 = new EntityWrapperHandle<EventresultvehicleinfoEntity>();
                ew1.setSqlSelect("count(*)", "`type`");
                ew1.eq("deviceid", host);
                ew1.between("createtime", start, end);
                ew1.groupBy("`type`");
                all.addAll(vehicleService.selectMaps(ew1));

                EntityWrapperHandle<EventresulttricyclesinfoEntity> ew2 = new EntityWrapperHandle<EventresulttricyclesinfoEntity>();
                ew2.setSqlSelect("count(*)", "`type`");
                ew2.eq("deviceid", host);
                ew2.between("createtime", start, end);
                ew2.groupBy("`type`");
                all.addAll(tricycleService.selectMaps(ew2));

                EntityWrapperHandle<EventresultpedestriansinfoEntity> ew3 = new EntityWrapperHandle<EventresultpedestriansinfoEntity>();
                ew3.setSqlSelect("count(*)", "`type`");
                ew3.eq("deviceid", host);
                ew3.between("createtime", start, end);
                ew3.groupBy("`type`");
                all.addAll(pedestrianService.selectMaps(ew3));

                EntityWrapperHandle<EventresultbikesinfoEntity> ew4 = new EntityWrapperHandle<EventresultbikesinfoEntity>();
                ew4.setSqlSelect("count(*)", "`type`");
                ew4.eq("deviceid", host);
                ew4.between("createtime", start, end);
                ew4.groupBy("`type`");
                all.addAll(bikeService.selectMaps(ew4));

                for (Map<String, Object> e : all) {
                    int type = JSONObject.parseObject((String) e.get("type")).getIntValue("Id");
                    if (type > 9 || type < 1) {
                        type = 0;
                    }
                    if (type > types[types.length - 1]) {
                        continue;
                    }
                    long count = (long) e.get("count(*)");
                    for (int i = 0; i < returnData.size(); i++) {
                        if (type == types[i]) {
                            long al = returnData.getJSONObject(i).getLongValue("total");
                            returnData.getJSONObject(i).put("total", (al + count));
                            break;
                        }
                    }
                }
            }
        }
        return returnData;
    }

    @ApiOperation("按天流量接口")
    @GetMapping("/flow/day")
    @CrossOrigin(origins = "*", maxAge = 86400)
    public JSONArray flowDay(@RequestParam Map<String, Object> data) throws ParseException {
        JSONArray returnData = new JSONArray();
        if (data != null && data.size() > 0) {
            String starttime = (String) data.get("starttime");
            String endtime = (String) data.get("endtime");
            if (isExist(starttime) && isExist(endtime)) {
                starttime = starttime + " 00:00:00";
                endtime = endtime + " 23:59:59";
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                Date s = sdf.parse(starttime);
                Date e = sdf.parse(endtime);
                double mil = e.getTime() - s.getTime();
                double oneDay = 86400000;
                int dayCount = (int) Math.round(mil / oneDay);
                if (dayCount > 0) {
                    Integer[] types = getIntArray((String) data.get("types"));
                    EntityWrapperHandle<DeviceinfoEntity> ew = new EntityWrapperHandle<DeviceinfoEntity>();
                    ew.setSqlSelect("deviceid");
                    List<DeviceinfoEntity> devices = deviceService.selectList(ew);
                    if (devices != null && devices.size() > 0) {
                        for (int i = 0; i < dayCount; i++) {
                            JSONArray day = new JSONArray();
                            for (DeviceinfoEntity deviceinfoEntity : devices) {
                                JSONObject device = new JSONObject();
                                device.put("deviceId", deviceinfoEntity.getDeviceid());
                                JSONArray info = new JSONArray();
                                for (int type : types) {
                                    JSONObject result = new JSONObject();
                                    result.put("resultType", type);
                                    result.put("total", 0);
                                    info.add(result);
                                }
                                device.put("info", info);
                                day.add(device);
                            }
                            returnData.add(day);
                        }
                        List<Map<String, Object>> all = new ArrayList<>();

                        EntityWrapperHandle<EventresultvehicleinfoEntity> ew1 = new EntityWrapperHandle<EventresultvehicleinfoEntity>();
                        ew1.setSqlSelect("`type`", "deviceid", "createtime");
                        ew1.between("createtime", starttime, endtime);
                        all.addAll(vehicleService.selectMaps(ew1));

                        EntityWrapperHandle<EventresulttricyclesinfoEntity> ew2 = new EntityWrapperHandle<EventresulttricyclesinfoEntity>();
                        ew2.setSqlSelect("`type`", "deviceid", "createtime");
                        ew2.between("createtime", starttime, endtime);
                        all.addAll(tricycleService.selectMaps(ew2));

                        EntityWrapperHandle<EventresultpedestriansinfoEntity> ew3 = new EntityWrapperHandle<EventresultpedestriansinfoEntity>();
                        ew3.setSqlSelect("`type`", "deviceid", "createtime");
                        ew3.between("createtime", starttime, endtime);
                        all.addAll(pedestrianService.selectMaps(ew3));

                        EntityWrapperHandle<EventresultbikesinfoEntity> ew4 = new EntityWrapperHandle<EventresultbikesinfoEntity>();
                        ew4.setSqlSelect("`type`", "deviceid", "createtime");
                        ew4.between("createtime", starttime, endtime);
                        all.addAll(bikeService.selectMaps(ew4));

                        long start = s.getTime();
                        for (Map<String, Object> map : all) {
                            double time = ((Date) map.get("createtime")).getTime() - start;
                            int order = (int) Math.floor(time / oneDay);
                            int type = JSONObject.parseObject((String) map.get("type")).getIntValue("Id");
                            if (type > 9 || type < 1) {
                                type = 0;
                            }
                            if (type > types[types.length - 1]) {
                                continue;
                            }
                            String deviceid = (String) map.get("deviceid");
                            for (int i = 0; i < devices.size(); i++) {
                                if (returnData.getJSONArray(order).getJSONObject(i).getString("deviceId").equals(deviceid)) {
                                    for (int j = 0; j < types.length; j++) {
                                        if (type == types[j]) {
                                            long al = returnData.getJSONArray(order).getJSONObject(i).getJSONArray("info").getJSONObject(j).getLongValue("total") + 1;
                                            returnData.getJSONArray(order).getJSONObject(i).getJSONArray("info").getJSONObject(j).put("total", al);
                                            break;
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        return returnData;
    }

    @ApiOperation("具体设备按天流量接口")
    @GetMapping("/flow/day/byid")
    @CrossOrigin(origins = "*", maxAge = 86400)
    public JSONArray flowDayById(@RequestParam Map<String, Object> data) throws ParseException {
        JSONArray returnData = new JSONArray();
        if (data != null && data.size() > 0) {
            String starttime = (String) data.get("starttime");
            String endtime = (String) data.get("endtime");
            String host = (String) data.get("host");
            if (isExist(starttime) && isExist(endtime) && isExist(host)) {
                starttime = starttime + " 00:00:00";
                endtime = endtime + " 23:59:59";
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                Date s = sdf.parse(starttime);
                Date e = sdf.parse(endtime);
                double mil = e.getTime() - s.getTime();
                double oneDay = 86400000;
                int dayCount = (int) Math.round(mil / oneDay);
                if (dayCount > 0) {
                    Integer[] types = getIntArray((String) data.get("types"));
                    for (int i = 0; i < dayCount; i++) {
                        JSONArray day = new JSONArray();
                        for (int type : types) {
                            JSONObject result = new JSONObject();
                            result.put("resultType", type);
                            result.put("total", 0);
                            day.add(result);
                        }
                        returnData.add(day);
                    }
                    List<Map<String, Object>> all = new ArrayList<>();

                    EntityWrapperHandle<EventresultvehicleinfoEntity> ew1 = new EntityWrapperHandle<EventresultvehicleinfoEntity>();
                    ew1.setSqlSelect("`type`", "createtime");
                    ew1.eq("deviceid", host);
                    ew1.between("createtime", starttime, endtime);
                    all.addAll(vehicleService.selectMaps(ew1));

                    EntityWrapperHandle<EventresulttricyclesinfoEntity> ew2 = new EntityWrapperHandle<EventresulttricyclesinfoEntity>();
                    ew2.setSqlSelect("`type`", "createtime");
                    ew2.eq("deviceid", host);
                    ew2.between("createtime", starttime, endtime);
                    all.addAll(tricycleService.selectMaps(ew2));

                    EntityWrapperHandle<EventresultpedestriansinfoEntity> ew3 = new EntityWrapperHandle<EventresultpedestriansinfoEntity>();
                    ew3.setSqlSelect("`type`", "createtime");
                    ew3.eq("deviceid", host);
                    ew3.between("createtime", starttime, endtime);
                    all.addAll(pedestrianService.selectMaps(ew3));

                    EntityWrapperHandle<EventresultbikesinfoEntity> ew4 = new EntityWrapperHandle<EventresultbikesinfoEntity>();
                    ew4.setSqlSelect("`type`", "createtime");
                    ew4.eq("deviceid", host);
                    ew4.between("createtime", starttime, endtime);
                    all.addAll(bikeService.selectMaps(ew4));

                    long start = s.getTime();
                    for (Map<String, Object> map : all) {
                        double time = ((Date) map.get("createtime")).getTime() - start;
                        int order = (int) Math.floor(time / oneDay);
                        int type = JSONObject.parseObject((String) map.get("type")).getIntValue("Id");
                        if (type > 9 || type < 1) {
                            type = 0;
                        }
                        if (type > types[types.length - 1]) {
                            continue;
                        }
                        for (int i = 0; i < types.length; i++) {
                            if (type == types[i]) {
                                long al = returnData.getJSONArray(order).getJSONObject(i).getLongValue("total") + 1;
                                returnData.getJSONArray(order).getJSONObject(i).put("total", al);
                                break;
                            }
                        }
                    }
                }
            }
        }
        return returnData;
    }

    public boolean isExist(String value) {
        return value != null && !value.equals("");
    }

    public Integer[] getIntArray(String s) {
        if (!isExist(s)) {
            return new Integer[]{0, 1, 2, 3, 4, 5, 6, 7, 8};
        }
        String[] str = s.split(",");
        List<Integer> list = new ArrayList<>();
        for (String value : str) {
            if (isInteger(value)) {
                list.add(Integer.parseInt(value));
            }
        }
        Collections.sort(list);
        return list.toArray(new Integer[0]);
    }

    public boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }
}